Friday, April 19, 2024

How do you foster collaboration between development, operations, and other teams in a Java project?

 

Fostering collaboration between development, operations, and other teams in a Java project requires a combination of communication, tools, and processes. Here are some strategies to help facilitate collaboration:




Establish clear communication channels: Use tools like Slack, Microsoft Teams, or similar platforms for real-time communication. Also, have regular meetings, such as daily stand-ups or weekly sync-ups, to keep everyone aligned and informed about project progress.

Encourage cross-functional teams: Form cross-functional teams comprising members from development, operations, QA, and other relevant departments. This helps in sharing knowledge and understanding each other's perspectives.

Implement DevOps practices: Embrace DevOps principles to bridge the gap between development and operations. Automate processes such as continuous integration, continuous delivery, and infrastructure provisioning to streamline collaboration and reduce bottlenecks.

Adopt Agile methodologies: Agile methodologies like Scrum or Kanban promote collaboration through iterative development cycles, regular feedback, and close collaboration between team members.

Use version control and collaboration tools: Leverage version control systems like Git along with collaboration platforms like GitHub or Bitbucket. These tools facilitate collaboration by allowing teams to work on the same codebase simultaneously and track changes effectively.

Provide training and knowledge sharing: Organize workshops, brown bag sessions, or knowledge-sharing sessions to educate team members about each other's roles, technologies, and best practices. Encourage learning and cross-training to build a more cohesive team.

Promote a culture of transparency and trust: Foster an environment where team members feel comfortable sharing their ideas, concerns, and feedback openly. Encourage transparency in decision-making processes and foster trust among team members.

Establish shared goals and metrics: Define common goals and metrics that align with both development and operations objectives. This encourages teams to collaborate towards shared outcomes and promotes a sense of collective responsibility.

Implement collaborative tools for project management: Utilize project management tools like Jira, Trello, or Asana to track tasks, assign responsibilities, and monitor progress collaboratively. Ensure that these tools are accessible to all team members and updated regularly.

Celebrate successes and learn from failures: Recognize and celebrate achievements as a team, whether it's delivering a successful release or overcoming a challenging issue. Similarly, encourage a blame-free culture where failures are seen as learning opportunities, and teams work together to identify solutions and prevent recurrence.

By implementing these strategies, you can foster a culture of collaboration and cooperation among development, operations, and other teams in a Java project, ultimately leading to improved efficiency, quality, and innovation.

Monday, March 25, 2024

Different AI tools for Intellij IDE and AI Plugins

There are several AI-powered tools and plugins available in the market that you can integrate with IntelliJ IDEA to enhance your development experience. These tools use AI and machine learning techniques to provide various features such as code completion, code analysis, refactoring suggestions, and more. Here are some popular AI tools and plugins for IntelliJ IDEA:



Code Completion & Suggestions:

1. Kite:

    Website: https://www.kite.com/

     Description: Kite provides AI-powered code completions and snippets.

      Features:

            Smart completions based on your code context.

            Documentation and examples for functions and libraries.

       IntelliJ Plugin: Kite PlugIn

2. TabNine:

       Website: TabNine

        Description: TabNine offers AI-driven code completion.

         Features:

                Predictive completions based on your coding patterns.

                Support for multiple languages.

           IntelliJ Plugin: TabNine Plugin

3. Codota:

          Website: Codota

          Description: Codota provides AI-powered code completions and suggestions.

          Features:

                     Contextual code suggestions.

                      Enhanced productivity with code snippets.

          IntelliJ Plugin: Codota Plugin


Code Analysis & Refactoring:

1. DeepCode:

          Website: DeepCode 

           Description: DeepCode uses AI to identify and fix issues in your code.

            Features:

                Automated code reviews.

                Real-time code analysis for potential errors.

                IntelliJ Plugin: DeepCode Plugin

2. SonarLint:

                Website: SonarLint

                Description: SonarLint offers AI-driven static code analysis.

                Features:

                    Code quality and security checks.

                    Real-time feedback on code issues.

                IntelliJ Plugin: SonarLint


Natural Language Processing (NLP) & Documentation:

1. NLP4J:

        Description: NLP4J provides natural language processing capabilities.

        Features:

                Tokenization, parsing, and entity recognition.

                Text summarization and keyword extraction.

           IntelliJ Plugin: NLP4J Plugin

2. DocTime:

          Description: DocTime helps generate code documentation.

           Features:

                Automatic code comments and documentation.

                Summarization of code blocks.

            IntelliJ Plugin: DocTime Plugin


Other AI Tools & Integrations:

1.TensorFlow Support:

             Description: Integration with TensorFlow for machine learning projects.

              Features:

                    TensorFlow model importing and execution.

                    TensorBoard integration.

                IntelliJ Plugin: TensorFlow Support Plugin


2. PyCharm AI Assisted Review:

               Description: AI-powered code reviews for Python projects.

               Features:

                        Automated code review suggestions.

                        Code style improvements.

                IntelliJ Plugin: PyCharm AI Assisted Review Plugin

3. Chatbot Integration:

                 Description: Integration with chatbot development platforms.

                  Features:

                         Chatbot code completion and suggestions.

                        Testing and debugging chatbot code.

                 IntelliJ Plugin: Chatbot Integration Plugin

 

Monday, March 18, 2024

What are the best practices for securing communication between microservices in a Java ecosystem

 

Securing communication between microservices in a Java ecosystem is crucial to protect sensitive data, prevent unauthorized access, and ensure the integrity and confidentiality of communication. Here are some best practices for achieving secure communication between microservices:






1. Transport Layer Security (TLS):

Use TLS/SSL for encrypting data transmitted over the network.

Enable HTTPS for RESTful APIs to ensure data confidentiality and integrity.

Configure mutual TLS (mTLS) for two-way authentication between services, where both client and server authenticate each other using certificates.

2. Service-to-Service Authentication:

Implement secure authentication mechanisms between microservices.

Use tokens (like JWT) or OAuth tokens for authentication and authorization.

Validate incoming tokens for each request to ensure only authorized services can access endpoints.

3. Role-Based Access Control (RBAC):

Implement RBAC to control access to microservice endpoints.

Define roles and permissions for each microservice, allowing only authorized users or services to perform specific actions.

4. API Gateway:

Use an API gateway to centralize security concerns and provide a single entry point for microservices.

Implement authentication, authorization, rate limiting, and request validation at the API gateway level.

5. Secure Service Discovery:

When using service discovery mechanisms like Eureka or Consul, ensure that service registration and discovery are secure.

Use authentication and encryption for communication between service registry and microservices.

6. Secure Configuration Management:

Store sensitive configuration properties (such as passwords, API keys) securely.

Use tools like Spring Cloud Config Server with encryption to manage and distribute configuration securely.

7. Secure Logging and Monitoring:

Implement secure logging practices to avoid logging sensitive information.

Use log encryption and centralized log management tools to monitor and detect security incidents.

8. Implement Content Validation:

Validate and sanitize input data to prevent injection attacks (e.g., SQL injection, XSS).

Use input validation libraries like Hibernate Validator or Bean Validation.

9. Container Security:

If deploying microservices in containers, ensure container images are scanned for vulnerabilities.

Implement least privilege principles for container permissions and avoid running containers with unnecessary privileges.

10. Use of Secure Protocols:

Avoid using insecure protocols such as HTTP and use HTTPS/TLS for secure communication.

Use protocols with strong security features like OAuth 2.0 for authentication and authorization.

11. Secure Message Queues:

If using message brokers (like RabbitMQ, Apache Kafka), ensure they are secured.

Use TLS/SSL for communication with the message broker.

Implement message encryption for sensitive data.

12. Data Encryption:

Encrypt sensitive data at rest and in transit.

Use libraries like Java Cryptography Architecture (JCA) or Bouncy Castle for encryption/decryption.

13. API Versioning and Deprecation:

Implement API versioning to manage changes in microservices.

Securely deprecate and remove old APIs to prevent security vulnerabilities in outdated endpoints.

14. Regular Security Audits and Penetration Testing:

Conduct regular security audits and vulnerability scans of microservices.

Perform penetration testing to identify potential security weaknesses and address them proactively.

15. Continuous Security Monitoring:

Implement continuous security monitoring using tools like Prometheus, Grafana, or ELK stack.

Monitor for suspicious activities, abnormal behaviors, or unauthorized access attempts.

Implement OAuth 2.0 Authorization Server and Resource Server in your microservices architecture.

Use JWT tokens for authentication and authorization between microservices.

Secure endpoints based on roles and scopes defined in JWT tokens.

Configure OAuth 2.0 clients for microservices to request and validate tokens.

Use Spring Cloud Gateway or Zuul as an API Gateway for centralized security enforcement.

Explain the SOLID principles and how they influence the design of Java applications.

 




The SOLID principles are a set of five design principles for writing clean, maintainable, and extensible object-oriented code. 

They were introduced by Robert C. Martin (also known as Uncle Bob) to guide developers in creating software that is easier to understand, modify, and scale. 

Here's an explanation of each principle and how they influence the design of Java applications:

1. Single Responsibility Principle (SRP):

The SRP states that a class should have only one reason to change, meaning it should have only one job or responsibility. 

This principle aims to keep classes focused and avoid bloated, tightly-coupled designs.

Influence on Java Design:

Helps create smaller, focused classes that are easier to understand and maintain.

Encourages separating concerns, such as separating business logic from data access or user interface.

Promotes the use of interfaces and abstractions to define contracts between components.

2. Open/Closed Principle (OCP):

The OCP states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. 

This means that the behavior of a module can be extended without modifying its source code.

Influence on Java Design:

Encourages the use of interfaces and abstract classes to define contracts.

Allows developers to add new functionality by creating new classes that implement existing interfaces or extend abstract classes.

Promotes the use of design patterns like Strategy, Decorator, and Factory to achieve extensibility without modifying existing code.

3. Liskov Substitution Principle (LSP):

The LSP states that objects of a superclass should be replaceable with objects of its subclasses without affecting the correctness of the program. In other words, subclasses should be substitutable for their base classes.

Influence on Java Design:

Encourages adherence to contracts defined by interfaces or base classes.

Promotes polymorphism and inheritance in a way that maintains consistency and behavior across classes.

Helps prevent unexpected behavior when using subclasses in place of their base classes.

4. Interface Segregation Principle (ISP):

The ISP states that clients should not be forced to depend on interfaces they do not use. It suggests that large interfaces should be broken down into smaller, more specific interfaces so that clients only need to know about the methods that are of interest to them.

Influence on Java Design:

Encourages the creation of cohesive and focused interfaces.

Helps avoid "fat" interfaces that require implementing unnecessary methods.

Facilitates easier implementation of interfaces by focusing on specific functionalities.

5. Dependency Inversion Principle (DIP):

The DIP states that high-level modules should not depend on low-level modules. Both should depend on abstractions. Additionally, abstractions should not depend on details; details should depend on abstractions.

Influence on Java Design:

Encourages the use of interfaces or abstract classes to define contracts between components.

Promotes loose coupling between classes by depending on abstractions rather than concrete implementations.

Facilitates easier unit testing and the ability to swap implementations without affecting the higher-level modules.

Influence on Java Applications:

Modularity: Applying SOLID principles helps create modular Java applications with smaller, more focused components.

Flexibility: Designing with SOLID principles allows for easier changes and extensions to the system without risking unintended side effects.

Readability and Maintainability: By promoting clean, well-structured code, SOLID principles make it easier for developers to understand and maintain Java applications.

Testability: Code designed with SOLID principles is typically easier to unit test, as it often results in classes that are more isolated and decoupled from dependencies.


In Java applications, adherence to the SOLID principles often leads to the use of design patterns such as Factory, Strategy, Decorator, and others. 

These patterns help implement the principles effectively, resulting in code that is more robust, flexible, and easier to maintain over time.

Saturday, March 9, 2024

what are different types of design patterns used in microservices

When designing microservices, there are several architectural patterns that can be used to achieve various goals such as scalability, fault tolerance, maintainability, and ease of deployment. Here are some common patterns used in microservices architecture:


1. Single Service Instance Pattern

Each microservice instance runs as a single instance. This is the simplest form of microservices architecture, where each service is deployed independently.

2. Service Instance per Container Pattern

Each microservice runs in its own container. Containers provide lightweight, isolated runtime environments for applications, allowing them to run consistently across different environments.

3. Service Instance per Virtual Machine Pattern

Each microservice runs in its own virtual machine (VM). This pattern provides a higher level of isolation compared to containers but comes with the overhead of managing VMs.

4. Shared Database Pattern

Multiple microservices share a common database. While this can simplify some aspects of development, it can also lead to tight coupling between services and make it difficult to evolve the system over time.

5. Database per Service Pattern

Each microservice has its own database. This pattern promotes loose coupling between services but requires careful coordination when data needs to be shared between services.

6. API Gateway Pattern

An API Gateway acts as a single entry point for clients to interact with multiple microservices. It can handle routing, authentication, and other cross-cutting concerns.

7. Aggregator Pattern

Aggregates data from multiple microservices into a single response for the client. This can reduce the number of client-server round trips and improve performance.

8. Saga Pattern

Manages distributed transactions across multiple microservices. A saga is a sequence of local transactions where each local transaction updates the database and publishes a message or event to trigger the next transaction.

9. Event Sourcing Pattern

Each microservice persists events as a log of changes to the system's state. This enables replaying events to rebuild state, auditing, and decoupling between services.

10. CQRS (Command Query Responsibility Segregation) Pattern

Separates read and write operations for a microservice. This pattern can improve scalability by allowing separate optimization for read and write operations.

11. Bulkhead Pattern

Isolates components of a system into separate pools to prevent failures in one component from affecting others. This helps improve fault tolerance and resilience.

12. Circuit Breaker Pattern

Monitors for failures and prevents cascading failures by temporarily blocking requests to a failing service. This pattern helps improve system stability.

13. Sidecar Pattern

Attaches a helper service, known as a "sidecar," to a microservice to provide additional functionality such as monitoring, logging, or security.

14. Strangler Pattern

Gradually replaces a monolithic application with microservices by "strangling" parts of the monolith with new microservices over time.

15. Choreography vs. Orchestration

In microservices, you often need to decide between choreography (decentralized coordination through events) and orchestration (centralized coordination through a service). This decision impacts how services communicate and coordinate their actions.

These patterns can be used individually or in combination to design a microservices architecture that meets the specific requirements of your application. It's essential to consider factors such as scalability, maintainability, fault tolerance, and team expertise when choosing the appropriate patterns for your system.





 

Wednesday, December 27, 2023

Getting started with Generative AI prompt engineer Step By Step Guide

 Generative AI prompt engineering involves crafting effective prompts to elicit desired responses from generative models.

Whether you're working with any models, the key is to provide clear and specific instructions. Here's a step-by-step guide to get started:

  1. Understand the Model's Capabilities:

    • Familiarize yourself with the capabilities and limitations of the generative model you're using. Understand the types of tasks it can perform and the formats it accepts.
  2. Define Your Goal:

    • Clearly define the goal of your prompt. Are you looking for creative writing, programming code, problem-solving, or something else? The specificity of your goal will guide your prompt creation.
  3. Start with a Clear Instruction:

    • Begin your prompt with a clear and concise instruction. Be specific about the type of output you're expecting. For example, if you want a creative story, you might start with "Write a short story about..."
  4. Provide Context or Constraints:

    • If necessary, provide additional context or constraints to guide the model. This can include setting, characters, tone, or any specific requirements. Constraints help to narrow down the output and make it more relevant to your needs.
  5. Experiment with Temperature and Max Tokens:

    • Generative models often come with parameters like "temperature" and "max tokens." Temperature controls the randomness of the output, and max tokens limit the length of the response. Experiment with these parameters to fine-tune the model's behavior.
  6. Iterate and Refine:

    • Don't be afraid to iterate and refine your prompts. Experiment with different instructions, wording, and structures to achieve the desired output. Analyze the model's responses and adjust your prompts accordingly.
  7. Use System and User Messages:

    • For interactive conversations with the model, you can use both system and user messages. System messages set the behavior of the assistant, while user messages simulate the user's input. This can be useful for multi-turn interactions.
  8. Handle Ambiguity:

    • If your prompt is ambiguous, the model might produce unexpected or undesired results. Clarify your instructions to reduce ambiguity and improve the likelihood of getting the desired output.
  9. Consider Prompt Engineering Libraries:

    • Some platforms provide prompt engineering libraries that simplify the process of crafting effective prompts. For example, OpenAI's Playground or other third-party libraries may offer useful tools and examples.
  10. Stay Ethical:

    • Be mindful of ethical considerations when generating content. Avoid prompts that may lead to harmful or inappropriate outputs. Review and filter the generated content to ensure it aligns with ethical guidelines.

Prompt engineering often involves a trial-and-error process. As you experiment and become familiar with the model's behavior, you'll improve your ability to craft effective prompts for generative AI.

Friday, December 8, 2023

API rate limiting strategies for Spring Boot applications

 


API Rate Limiting

 Rate limiting is a strategy to limit access to APIs. 

 It restricts the number of API calls that a client can make within a certain time frame. 

 This helps defend the API against overuse, both unintentional and malicious.


API rate limiting is crucial for maintaining the performance, stability, and security of Spring Boot applications. Here are several rate limiting strategies you can employ:


1. Fixed Window Counter:

In this strategy, you set a fixed window of time (e.g., 1 minute), and you allow a fixed number of requests within that window. If a client exceeds the limit, further requests are rejected until the window resets. This approach is simple but can be prone to bursts of traffic.


2. Sliding Window Counter:

A sliding window counter tracks the number of requests within a moving window of time. This allows for a more fine-grained rate limiting mechanism that considers recent activity. You can implement this using a data structure like a sliding window or a queue to track request timestamps.


3. Token Bucket Algorithm:

The token bucket algorithm issues tokens at a fixed rate. Each token represents permission to make one request. Clients consume tokens for each request, and requests are only allowed if there are available tokens. Google's Guava library provides a RateLimiter class that implements this algorithm.


4. Leaky Bucket Algorithm:

Similar to the token bucket, the leaky bucket algorithm releases tokens at a constant rate. However, in the leaky bucket, the bucket has a leak, allowing it to empty at a constant rate. Requests are processed as long as there are tokens available. This strategy can help smooth out bursts of traffic.

5. Distributed Rate Limiting with Redis or Memcached:

If your Spring Boot application is distributed, you can use a distributed caching system like Redis or Memcached to store and share rate limiting information among different instances of your application.


6. Spring Cloud Gateway Rate Limiting:

If you're using Spring Cloud Gateway, it provides built-in support for rate limiting. You can configure rate limiting policies based on various criteria such as the number of requests per second, per user, or per IP address.


7. User-based Rate Limiting:

Instead of limiting based on the number of requests, you can implement rate limiting on a per-user basis. This is useful for scenarios where different users may have different rate limits based on their subscription level or user type.


8. Adaptive Rate Limiting:

Implement adaptive rate limiting that dynamically adjusts rate limits based on factors such as server load, response times, or the health of the application. This approach can help handle variations in traffic.


9.Response Code-based Rate Limiting:

Consider rate limiting based on response codes. For example, if a client is generating a high rate of error responses, you might want to impose stricter rate limits on that client.


10. API Key-based Rate Limiting:

Tie rate limits to API keys, allowing you to set different limits for different clients or users. This approach is common in scenarios where you have third-party developers using your API.

Thursday, June 15, 2023

How to install Kong Gateway using Docker

To install Kong Gateway, you can follow these steps: 

 Step 1: Choose the installation method: 
  
     Kong Gateway offers different installation methods depending on your operating system and
     requirements. 

    You can choose from Docker, package managers (e.g., Homebrew, Yum, Apt), or manual installation.

     For simplicity, let's go with the Docker installation method.

 Step 2: Install Docker: If you don't have Docker installed, visit the Docker website
              (https://www.docker.com/) and follow the instructions to install Docker for your specific
               operating system. 

 Step 3: Pull the Kong Gateway Docker image: 
 
             Open a terminal or command prompt. Run the following command to pull the Kong Gateway
              Docker image from Docker Hub:
docker pull kong/kong-gateway

Step 4: Run Kong Gateway container: Once the image is pulled, run the following command to start a
             Kong Gateway
docker run -d --name kong-gateway \
  -e "KONG_DATABASE=off" \
  -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
  -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
  -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
  -e "KONG_PROXY_LISTEN=0.0.0.0:8000" \
  -p 8000:8000 \
  -p 8001:8001 \
  kong/kong-gateway

This command starts a Kong Gateway container named "kong-gateway" with the necessary environment variables and port mappings. 

 The -p option maps the container's ports to the host machine, allowing access to Kong Gateway's admin API (port 8001) and proxy API (port 8000). 

 The -e options set various environment variables like the database type (KONG_DATABASE=off disables the database), log configurations, and listen addresses.

 Step 5: Verify Kong Gateway installation: After running the container, wait for a few moments to allow
              Kong Gateway to initialize. 


You can check the logs of the container using the following command:
docker logs kong-gateway

Look for any error messages or indications that Kong Gateway has started successfully. 


 Step 6: Access Kong Gateway admin API: 

 Once Kong Gateway is running, you can access its admin API to configure and manage your Kong Gateway instance. 

Open a web browser and go to http://localhost:8001. You should see the Kong Gateway admin API homepage if everything is working correctly.

 Congratulations! You have successfully installed Kong Gateway using Docker. 

You can now proceed with configuring Kong Gateway and integrating it with your applications as needed

Monday, May 1, 2023

How to Implement Image classification using TensorFlow maven and Java

Here is an example of using TensorFlow with Java and Maven to perform image classification: 

 1.Create a new Maven project in your favorite IDE. 

 2. Add the TensorFlow Java dependency to your project by adding the following to your pom.xml file:

    
      <dependencies>
    <dependency>
        <groupId>org.tensorflow</groupId>
        <artifactId>tensorflow</artifactId>
        <version>2.7.0</version>
    </dependency>
</dependencies>
    

3. Create a new class, for example ImageClassifier.java, and add the following code:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.tensorflow.DataType;
import org.tensorflow.Graph;
import org.tensorflow.Session;
import org.tensorflow.Tensor;
import org.tensorflow.TensorFlow;

public class ImageClassifier {
    private static byte[] loadImage(String path) throws IOException {
        BufferedImage img = ImageIO.read(new File(path));
        int height = img.getHeight();
        int width = img.getWidth();
        int channels = 3;
        byte[] data = new byte[height * width * channels];
        int pixel = 0;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                int rgb = img.getRGB(j, i);
                data[pixel++] = (byte) ((rgb >> 16) & 0xFF);
                data[pixel++] = (byte) ((rgb >> 8) & 0xFF);
                data[pixel++] = (byte) (rgb & 0xFF);
            }
        }
        return data;
    }

    public static void main(String[] args) throws Exception {
        // Load the TensorFlow library
        try (Graph g = new Graph()) {
           byte[] graphBytes = TensorFlowModelLoader.load("path/to/model.pb");
            g.importGraphDef(graphBytes);

            // Create a new session to run the graph
            try (Session s = new Session(g)) {
                // Load the image data
                String imagePath = "path/to/image.jpg";
                byte[] imageBytes = loadImage(imagePath);

                // Create a tensor from the image data
                Tensor inputTensor = Tensor.create(new long[]
                                   {1, imageBytes.length}, ByteBuffer.wrap(imageBytes));

                // Run the graph on the input tensor
                Tensor outputTensor = s.runner()
                        .feed("input", inputTensor)
                        .fetch("output")
                        .run()
                        .get(0);

                // Print the predicted label
                DataType outputDataType = outputTensor.dataType();
                long[] outputShape = outputTensor.shape();
                Object[] output = new Object[outputTensor.numElements()];
                outputTensor.copyTo(output);
                System.out.println("Prediction: " + output[0]);
            }
        }
    }
}
4. Replace the path/to/model.pb and path/to/image.jpg with the actual paths to your model and image files. 

 5. Run the ImageClassifier class, and it should print out the predicted label for the input image.

Thursday, April 13, 2023

How to create key cloak authentication server and spring boot

To create a Keycloak authentication server, you need to follow these steps: 

 1. Download and Install Keycloak: You can download Keycloak from the official website     

 Follow the installation instructions provided in the documentation. 

 2. Configure Keycloak: Once installed, you need to configure Keycloak by creating a new realm. 
     A realm is a container for all the users, roles, and groups in your application.

    To create a new realm, log in to the Keycloak admin console using the default credentials
      (admin/admin), then follow these steps:

      Click on the "Add Realm" button and provide a name for your realm. 

      Configure your realm settings, including themes, email settings, and login settings. 

      Create users and groups within your realm and assign roles to them. 

 3. Set Up Your Spring Boot Application: You can use the Keycloak Spring Boot Starter dependency to
      add Keycloak authentication to your Spring Boot application.

      Add the following dependency to your Maven or Gradle build file:

<dependency>
  <groupId>org.keycloak</groupId>
  <artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>


4. Configure Your Spring Boot Application: You need to configure your Spring Boot application to
     connect to the Keycloak server. 

     You can do this by adding the following properties to your application.properties or application.yml file:
keycloak.auth-server-url=<keycloak-server-url>
keycloak.realm=<keycloak-realm>
keycloak.resource=<keycloak-client-id>
keycloak.credentials.secret=<keycloak-client-secret>


   Replace <keycloak-server-url>, <keycloak-realm>, <keycloak-client-id>, 
    and <keycloak-client-secret> with the appropriate values for your Keycloak instance.

 5.  Secure Your Spring Boot Application: You can secure your Spring Boot application by adding the
      Keycloak configuration to your Spring Security configuration. 

      You can do this by creating a new class that extends KeycloakWebSecurityConfigurerAdapter and
      override the configure method. 

Here's an example:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(keycloakAuthenticationProvider());
    }

    @Bean
    public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests().antMatchers("/admin/**").hasRole("admin")
          .antMatchers("/user/**").hasAnyRole("user", "admin")
          .anyRequest().permitAll();
    }
}
    This configuration class enables Keycloak authentication and authorization for specific URLs in the
     application.

 6. Test Your Application: You can test your application by running it and accessing the protected URLs.
     When a user tries to access a protected resource, they will be redirected to the Keycloak login page.
      Once they successfully authenticate, they will be redirected back to the original resource. 

That's it! we have created a Keycloak authentication server and secured your Spring Boot application with it.

Wednesday, April 12, 2023

How to build video conference using spring boot

To build a video conference application using Spring Boot, you can follow these steps: 

 1. Choose a video conferencing API: There are several video conferencing APIs available such as Twilio, Agora, Zoom, Jitsi, etc. Choose an API that best fits your requirements. 

 2. Set up a Spring Boot project: Create a new Spring Boot project using your preferred IDE or by using Spring Initializr. 

 3. Add the video conferencing API dependencies: Add the necessary dependencies for the chosen API in your project's pom.xml file.

 4. Configure the video conferencing API: Configure the video conferencing API with the required credentials and other settings in your Spring Boot application's configuration file.

 5. Implement the video conferencing features: Use the API's SDK to implement the video conferencing features such as creating a conference room, joining a room, leaving a room, etc. 

 6. Integrate the video conferencing features with your application: Add the necessary controllers and views to your Spring Boot application to integrate the video conferencing features with your application. 

 7. Test the application: Test the application thoroughly to ensure that the video conferencing features are working as expected. 

 Here's a sample code for a video conference application using Spring Boot and the Twilio Video API:
 1. Add the Twilio Video API dependency to your pom.xml file:

 

<dependency>
    <groupId>com.twilio.sdk</groupId>
    <artifactId>twilio</artifactId>
    <version>7.54.0</version>
</dependency>



2. Add the required Twilio credentials and settings to your Spring Boot application's application.properties file
twilio.account.sid=your_account_sid
twilio.auth.token=your_auth_token
twilio.api.key=your_api_key
twilio.api.secret=your_api_secret
twilio.video.room.max-participants=4
3. Implement a controller for creating and joining a video conference room:
@RestController
public class VideoConferenceController {

    @Autowired
    private TwilioConfig twilioConfig;

    @PostMapping("/room")
    public ResponseEntity createRoom() throws Exception {
        RoomCreator roomCreator = Room.creator()
                .setUniqueName(UUID.randomUUID().toString())
                .setType(RoomType.PEER_TO_PEER)
                .setStatusCallback(twilioConfig.getStatusCallback())
                .setMaxParticipants(twilioConfig.getMaxParticipants());
        Room room = roomCreator.create();
        RoomResponse response = new RoomResponse();
        response.setRoomId(room.getSid());
        response.setRoomName(room.getUniqueName());
        response.setToken(createAccessToken(room.getSid()));
        return ResponseEntity.ok(response);
    }

    @GetMapping("/room/{roomId}/token")
    public ResponseEntity 
                        getRoomToken(@PathVariable("roomId") String roomId) {
        String accessToken = createAccessToken(roomId);
        return ResponseEntity.ok(accessToken);
    }

    private String createAccessToken(String roomId) {
        VideoGrant grant = new VideoGrant();
        grant.setRoom(roomId);
        AccessToken token = new AccessToken.Builder(
                twilioConfig.getAccountSid(),
                twilioConfig.getApiKey(),
                twilioConfig.getApiSecret()
        ).identity(UUID.randomUUID().toString())
                .grant(grant)
                .build();
        return token.toJwt();
    }

}
4.Define a configuration class for the Twilio settings:
@ConfigurationProperties(prefix = "twilio")
@Data
public class TwilioConfig {

    private String accountSid;
    private String authToken;
    private String apiKey;
    private String apiSecret;
    private String statusCallback;
    private int maxParticipants;


}


5.Configure the Twilio settings in your Spring Boot application's application.yml file:
twilio:
  account-sid: your_account_sid
  auth-token: your_auth_token
  api-key: your_api_key
  api-secret: your_api_secret
  status-callback: http://localhost:8080/callback
  max-participants: 4
  
  
6. Run your Spring Boot application and test the video conference feature by creating and joining a room using the API endpoints.

Tuesday, March 14, 2023

Oracle Cloud Infrastructure- Object storage example

This post will explain, how we can create bucket and configure notification and rules and object storage like create/update object. Login into OCI using login credentials . if you don't have a account please create the same using this link https://www.oracle.com/cloud/sign-in.html Once you create account and successful login, Now we need to create a bucket. search for bucket and create a bucket
After creating bucket now we can create a topic
Now we can create notification, after uploading file , we should get email
Create a Rule to process this
Once we create all then , once we upload file in object storage , then we should get email like below
This shows we can send email, but we can configure with different ways like queues. Here we will get the details in mail . But if we want complete object details, then we can use java code to retrieve the object details by calling the API which required namespace details ,bucket name and object name.
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Paths;
import java.util.List;

import com.oracle.bmc.objectstorage.ObjectStorage;
import com.oracle.bmc.objectstorage.ObjectStorageClient;
import com.oracle.bmc.objectstorage.model.GetObjectRequest;
import com.oracle.bmc.objectstorage.model.ObjectStream;
import com.oracle.bmc.objectstorage.model.Range;
import com.oracle.bmc.objectstorage.requests.GetObjectRequest;
import com.oracle.bmc.objectstorage.responses.GetObjectResponse;

public class LogFileRetriever {
    public static void main(String[] args) {
        String namespaceName = "mynamespace";
        String bucketName = "mybucket";
        String objectName = "mylogfile.txt";

        // Create a new Object Storage client
        ObjectStorage objectStorageClient = ObjectStorageClient.builder()
                .build(objectStorageConfig);

        GetObjectRequest request = GetObjectRequest.builder()
                .namespaceName(namespaceName)
                .bucketName(bucketName)
                .objectName(objectName)
                .build();

        GetObjectResponse response = objectStorageClient.getObject(request);

        // Get the InputStream from the response
        InputStream logFileInputStream = response.getInputStream();

        // Write the InputStream to a local file
        OutputStream logFileOutputStream = 
            new FileOutputStream(Paths.get("logfile.txt").toFile());
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = logFileInputStream.read(buffer)) != -1) {
            logFileOutputStream.write(buffer, 0, bytesRead);
        }
        logFileOutputStream.close();
    }
}

Monday, March 14, 2022

How to call REST API Using Spring Webflux WebClient set proxy with authorization while calling the external site and Generate base 64 authentication header spring boot

This post will explain us, how can we call REST API using Webclient. How to set Proxy username and password to call the external site. Step 1: Add folllowing dependency in your pom.xml
   
	 org.springframework.boot
	 spring-boot-starter-webflux
	
Step 2:
import lombok.extern.slf4j.XSlf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.transport.ProxyProvider;

import java.net.URI;
import java.util.Base64;
import java.util.function.Consumer;
import java.util.function.Function;
 public static void main(String[] args) {
  try {
  //Generate HttP client to set proxy details
  HttpClient httpClient = HttpClient.create()
            .proxy(proxy-> proxy.type(ProxyProvider.Proxy.HTTP)
            .host("javaguruonline.com").port(1328)
            .username("siva")
            .password(new Function() {
                        @Override
                        public String apply(String s) {
                            return "test@12!";
                        }
                    }));
  ClientHttpConnector clientHttpConnector = 
           new ReactorClientHttpConnector(httpClient);
  WebClient webClient = WebClient.builder().build();
  String plainCredentials = "username" + ":" + "password";
  String base64Credentials = new String(Base64.getEncoder()
                           .encode(plainCredentials.getBytes()));
  String authorizationHeader = "Basic " + base64Credentials;
  //input json
  String json = "{\n" +
                    "  \"user\": \"siva\"\n" +
                    "}";
            //set http headers
  Consumer httpHeaders = new Consumer() {
     @Override
     public void accept(HttpHeaders httpHeaders) {
       httpHeaders.add("Authorization", authorizationHeader);
       httpHeaders.add("Content-Type", "application/json");
       httpHeaders.add("Proxy-Authorization", authorizationHeader);
     }};
   //post call to external URL and get ResponseEntity as response like body 
   //and http status code etc..
    ResponseEntity result = webClient.mutate()
                    .clientConnector(clientHttpConnector)
                    .build()
                    .post()
                    .uri(new URI("https://localhost:8080/test/details"))
                    .bodyValue(json)
                    .accept(MediaType.APPLICATION_JSON)
                    .retrieve()
                    .toEntity(String.class)
                    .block();
            System.out.println(result);
        }
        catch(Exception ex){
        }
Hope this post will help some one, while working on the REST API calls

Thursday, March 11, 2021

How to mock ResultSet , NamedParameterJdbcTemplate , RowMapper

package com.siva.springboot.javaguruonline.repository;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import com.siva.springboot.javaguruonline.model.EmployeeDetails;
@RunWith(SpringRunner.class)
/**
 * 
 * @author Siva
 *
 */
//@SpringBootTest(classes = SpringbootJpaSwaggerSonarqubeApplication.class)
public class EmployeeDaoImplTest {
	
	@InjectMocks
	public EmployeeDaoImpl employeeDao;
	
	@Mock
	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
	
	@SuppressWarnings("unchecked")
	@Test
	public void testGetAllEmployeeDetails(){
		List list = new ArrayList();
		EmployeeDetails employeeDetails = new EmployeeDetails();
		employeeDetails.setEmpId(1);
		employeeDetails.setEmpName("siva");
		list.add(employeeDetails);
		Mockito.when(namedParameterJdbcTemplate.query(Mockito.anyString(),
        Mockito.any(RowMapper.class)))
	    .thenAnswer(new Answer>() {
		
	        @Override
	public List answer(InvocationOnMock invocation) 
                                          throws Throwable {
	            // Fetch the method arguments
	          Object[] args = invocation.getArguments();
	          

	            // Fetch the row mapper instance from the arguments
	          RowMapper rm = (RowMapper) args[1];

	          // Create a mock result set and setup an expectation on it
	          ResultSet rs = Mockito.mock(ResultSet.class);
	          Mockito.when(rs.getInt("emp_id")).thenReturn(employeeDetails.getEmpId());
	            
	          Mockito.when(rs.getString("emp_name")).thenReturn(employeeDetails.getEmpName());
               
	            // Invoke the row mapper
	          EmployeeDetails actual = rm.mapRow(rs, 0);
	            // Assert the result of the row mapper execution
	          Assert.assertEquals(employeeDetails.getEmpName(), actual.getEmpName());

	            // Return your created list for the template#query call
	            return list;
	        }
	    });
		
		
		
		
		 employeeDao.getEmployeeDetails();
		Assert.assertNotNull(list);
	}

}

AddToAny

Contact Form

Name

Email *

Message *